﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using System.Linq.Expressions;

namespace Web.Framework.Helpers
{
    public static class SortExpressionBuilder<T>
    {
        private static List<ISortExpression> directions = new List<ISortExpression>
        {
            { new OrderByAscendingSortExpression() },
            { new OrderByDescendingSortExpression() }
        };

        interface ISortExpression
        {
            Func<IEnumerable<T>, Func<T, object>, IEnumerable<T>> GetExpression();
        }

        class OrderByAscendingSortExpression : ISortExpression
        {
            public Func<IEnumerable<T>, Func<T, object>, IEnumerable<T>> GetExpression()
            {
                return (c, f) => c.OrderBy(f);
            }
        }


        class OrderByDescendingSortExpression : ISortExpression
        {
            public Func<IEnumerable<T>, Func<T, object>, IEnumerable<T>> GetExpression()
            {
                return (c, f) => c.OrderByDescending(f);
            }
        }

        public static Func<IEnumerable<T>, Func<T, object>, IEnumerable<T>> CreateExpression(SortDirection direction)
        {
            return directions[(int)direction].GetExpression();
        }       
    }

    public static class GridSortingExtenssion
    {
        public static IEnumerable<T> OrderByForGrid<T>(this IEnumerable<T> collection, string columnName, SortDirection direction)
        {
            ParameterExpression param = Expression.Parameter(typeof(T), "x"); // x
            Expression property = Expression.Property(param, columnName); //x.ColumnName
            Func<T, object> func = Expression.Lambda<Func<T, object>>(Expression.Convert(property, typeof(object)), param).Compile(); // x => x.ColumnName
            return SortExpressionBuilder<T>.CreateExpression(direction)(collection, func);
        } 
    }
}
